package la.iok.hzsvn.lewin.movie.service;

import la.iok.hzsvn.lewin.movie.core.Token;
import la.iok.hzsvn.lewin.movie.core.exception.ErrorCode;
import la.iok.hzsvn.lewin.movie.core.model.PlayRoleVo;
import la.iok.hzsvn.lewin.movie.entity.PlayRole;
import la.iok.hzsvn.lewin.movie.mapper.PlayRoleMapper;
import la.iok.hzsvn.lewin.movie.model.PlayRoleParam;
import la.iok.hzsvn.lewin.mybatis.service.BaseServiceImpl;
import la.iok.hzsvn.share.annotations.NotNull;
import la.iok.hzsvn.share.annotations.NotNullElement;
import la.iok.hzsvn.share.annotations.Nullable;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class PlayRoleServiceImpl extends BaseServiceImpl<PlayRole,PlayRoleMapper,Long> implements PlayRoleService{
    private static final String[] GENDER_ARR = new String[]{"男","女"};
    private static final String[] CROSS_GENDER_ARR = new String[]{"可","不可"};

    private final MovieService movieService;
    private final PlayRoleFileService playRoleFileService;

    public PlayRoleServiceImpl(MovieService movieService,
                               PlayRoleMapper playRoleMapper,
                               PlayRoleFileService playRoleFileService) {
        super(playRoleMapper);
        this.movieService = movieService;
        this.playRoleFileService = playRoleFileService;
    }

    @Override
    public Long save(@NotNull Token token, @NotNull Long movieId, @NotNull PlayRoleParam playRole) {
        validatePlayRole(playRole);
        movieService.validate(token,movieId);
        PlayRole entity = new PlayRole();
        BeanUtils.copyProperties(playRole,entity);
        entity.setMovieId(movieId);
        mapper.insertSelective(entity);
        return entity.getId();
    }

    private void validatePlayRole(@NotNull PlayRoleParam playRole) {
        ErrorCode.PROPERTY_CHECK_ERROR.assertAnyOf(playRole.getGender(),GENDER_ARR,"性别","性别只能是男或者女");
        ErrorCode.PROPERTY_CHECK_ERROR.assertAnyOf(playRole.getCrossGender(),CROSS_GENDER_ARR,"反串","反串的可能值只能是可或不可");
        playRole.setName(ErrorCode.PROPERTY_CHECK_ERROR.assertNotBlank(playRole.getName(),"名称","名称不能为空"));
    }

    @Override
    public void update(@NotNull Token token, @NotNull Long id, @NotNull PlayRoleParam playRole) {
        validatePlayRole(playRole);
        PlayRole role = select(id);
        ErrorCode.PLAY_ROLE_NOT_EXIST.assertNotNull(role,id);
        movieService.validate(token,role.getMovieId());
        BeanUtils.copyProperties(playRole,role);
        mapper.updateSelective(role);
    }

    @Transactional
    @Override
    public void uploadFile(@NotNull Token token, @NotNull Long id, @NotNull String path, @NotNull MultipartFile file) {
        path = ErrorCode.STORE_PATH_EMPTY_ERROR.assertNotBlank(path);
        PlayRole entity = select(id);
        ErrorCode.PLAY_ROLE_NOT_EXIST.assertNotNull(entity,id);
        movieService.validate(token,entity.getMovieId());
        Long fileId = playRoleFileService.uploadFile(file);
        playRoleFileService.decrement(entity.getFileId());
        update(id,"fileId",fileId);
        update(id,"filePath",path);
        playRoleFileService.increment(fileId);
    }

    @Override
    public void downloadFile(Token token, HttpServletResponse response, Long id) {
        PlayRole entity = validate(token,id);
        playRoleFileService.downloadFile(response,entity.getFileId(),entity.getName());
    }

    private PlayRole validate(@NotNull Token token, @NotNull Long id) {
        PlayRole role = select(id);
        ErrorCode.PLAY_ROLE_NOT_EXIST.assertNotNull(role,id);
        movieService.validate(token,role.getMovieId());
        return role;
    }

    @Transactional
    @Override
    public void delete(@NotNull Token token, @NotNull Long id) {
        PlayRole role = validate(token,id);
        playRoleFileService.decrement(role.getFileId());
        delete(id);
    }

    @NotNull
    @NotNullElement
    @Override
    public List<PlayRole> list(@Nullable Long movieId) {
        if(movieId == null){
            return Collections.emptyList();
        }
        return mapper.listByProperty("movieId",movieId);
    }

    @Override
    public List<PlayRoleVo> movieRoles(@NotNull Token token, @Nullable Long movieId) {
        movieService.validate(token,movieId);
        List<PlayRole> list = list(movieId);
        return list.stream().map(this::po2vo).collect(Collectors.toList());
    }

    @NotNull
    private PlayRoleVo po2vo(@NotNull PlayRole entity){
        PlayRoleVo vo = new PlayRoleVo();
        BeanUtils.copyProperties(entity,vo);
        return vo;
    }

    @Nullable
    @Override
    public String digest(@Nullable Long id) {
        PlayRole entity = select(id);
        ErrorCode.ROLE_NOT_EXIST.assertNotNull(entity,id);
        return playRoleFileService.digest(entity.getFileId());
    }

    @Nullable
    @Override
    public String storePath(@Nullable Long id) {
        PlayRole entity = select(id);
        ErrorCode.ROLE_NOT_EXIST.assertNotNull(entity,id);
        return playRoleFileService.storePath(entity.getFileId());
    }
}
